﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AuctionDataLayer.Models;


namespace AuctionDataLayer
{
    class CalculateAmountToPay
    {
        //copy method
        public static UserInGroupCloneModel CopyUserInGroup(UserInGroup model)
        {
            UserInGroupCloneModel result = new UserInGroupCloneModel();
            result.id = model.Id;
            result.userId = model.UserId;
            result.groupId = model.GroupId;
            result.creditAdded = model.CreditAdded;
            model.CreditAddedSpent = model.CreditAddedSpent;
            model.ActiveMember = model.ActiveMember;
            return result;
        }

        public static List<ToPayModel> CalculateAmountSubstract(IEnumerable<UserInGroup> members, int bidAmount)
        {
            List<ToPayModel> result = new List<ToPayModel>();
            List<UserInGroupCloneModel> remainingMembers = new List<UserInGroupCloneModel>();

            foreach (var item in members)
            {
                var available = item.CreditAdded - item.CreditAddedSpent;
                if (available == 0)
                {
                    var temp = new ToPayModel();
                    temp.amountToPay = available;
                    temp.userId = item.UserId;
                    result.Add(temp);
                }
                else
                {
                    remainingMembers.Add(CopyUserInGroup(item));
                }
            }

            var membersCount = remainingMembers.Count();
            var min = 0;
            var minEach = 0;

            if (membersCount == 0)
            {

            }
            else
            {
                min = remainingMembers.Min(x => x.creditAdded - x.creditAddedSpent);
                //Floored
                minEach = bidAmount / membersCount;             
            }

            //If all can affort to play equally
            if (min > minEach)
            {
                foreach (var item in remainingMembers)
                {
                    var temp = new ToPayModel();
                    temp.amountToPay = minEach;
                    temp.userId = item.userId;
                    result.Add(temp);
                }
                return result;
            }
            else
            {
                var removedAmount = 0;
                double minPayEach = min;
                membersCount = remainingMembers.Count();
                while (minPayEach * membersCount <= bidAmount - removedAmount && membersCount > 0 && removedAmount < bidAmount)
                {
                    foreach (var item in remainingMembers.ToList())
                    {
                        item.creditAddedSpent += Convert.ToInt32(minPayEach);
                        var singleRemaining = item.creditAdded - item.creditAddedSpent;
                        var temp = new ToPayModel();
                        temp.amountToPay = Convert.ToInt32(minPayEach);
                        temp.userId = item.userId;
                        if (singleRemaining == 0)
                        {
                            remainingMembers.Remove(item);
                        }
                        result.Add(temp);
                        removedAmount += Convert.ToInt32(minPayEach);
                    }
                    membersCount = remainingMembers.Count();
                    if (membersCount > 0)
                    {
                        min = remainingMembers.Min(x => x.creditAdded - x.creditAddedSpent);
                        minPayEach = bidAmount - removedAmount / membersCount;
                        if (min < minPayEach)
                        {
                            minPayEach = min;
                        }
                    }
                }
                //remove duplicates
                List<ToPayModel> result2 = new List<ToPayModel>();
                foreach (var item in members)
                {
                    var temp = new ToPayModel();
                    temp.amountToPay = (result.Where(x => x.userId == item.UserId).Select(x => x.amountToPay)).Sum();
                    temp.userId = item.UserId;
                    result2.Add(temp);
                }
                return result2;
            }
        }
    }
}
